package com.youfan.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.youfan.entity.YoufanProduct;
import com.youfan.mapper.ProductMapper;
import com.youfan.page.CommonPage;
import com.youfan.service.ProductService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
@CacheConfig(cacheNames = "YouFanCache")
public class ProductServiceImpl extends ServiceImpl<ProductMapper, YoufanProduct> implements ProductService {
    Logger logger= LoggerFactory.getLogger(ProductServiceImpl.class);
    private static final String KEY = "ProductServiceImpl";
    @Autowired
    private ProductMapper productMapper;


    @Override
    public int insertOne(YoufanProduct youfanProduct) {
        youfanProduct.setCreateTime(new Date());
        youfanProduct.setApproveStatus(0);
        youfanProduct.setDeleteStatus(0);
        youfanProduct.setPublishStatus(1);
        youfanProduct.setNewStatus(0);
        return productMapper.insert(youfanProduct);
    }
    @SentinelResource(value = KEY, blockHandler = "queryByCondtionBlockHandlerMethod", fallback = "queryByCondtionFallback")
    @Override
    public CommonPage<YoufanProduct> queryByCondtion(YoufanProduct youfanProduct) {
        PageHelper.startPage(youfanProduct.getPageNum(),youfanProduct.getPageSize());
        QueryWrapper queryWrapper = new QueryWrapper();
        if(StringUtils.isNotBlank(youfanProduct.getName())){
            queryWrapper.like("name", youfanProduct.getName());
        }
        if(StringUtils.isNotBlank(youfanProduct.getTitle())){
            queryWrapper.like("title", youfanProduct.getTitle());
        }
        if(youfanProduct.getProductTypeid() !=  null ){
            queryWrapper.eq("product_typeid", youfanProduct.getProductTypeid());
        }
        if(youfanProduct.getBrandid() !=  null ){
            queryWrapper.eq("brandid", youfanProduct.getBrandid());
        }
        if(youfanProduct.getApproveStatus() !=  null ){
            queryWrapper.eq("approve_status", youfanProduct.getApproveStatus());
        }
        if(StringUtils.isNotBlank(youfanProduct.getDescription())){
            queryWrapper.like("description", youfanProduct.getDescription());
        }



        List<YoufanProduct> list = productMapper.selectList(queryWrapper);


        return CommonPage.restPage(list);
    }
    @Cacheable(value = "YouFanCache",key = "#youfanProduct.id")
    @SentinelResource(value = KEY, blockHandler = "findByidHandler", fallback = "findByidFallback")
    @Override
    public YoufanProduct findByid(YoufanProduct youfanProduct) {
        logger.info("==================》findByid(YoufanProduct youfanProduct)");
        return productMapper.selectById(youfanProduct.getId());
    }


    @CachePut(value = "YouFanCache",key = "#youfanProduct.id")
    @Override
    public YoufanProduct updateOne(YoufanProduct youfanProduct) {
        logger.info("===============》updateOne(YoufanProduct youfanProduct)");
        youfanProduct.setUpdateTime(new Date());
        productMapper.updateById(youfanProduct);
        YoufanProduct youfanProduct_persist=productMapper.selectById(youfanProduct.getId());
        return youfanProduct_persist;
    }

    /**
     * 流量消峰控件
     */
    @PostConstruct
    public void initDegradeRule() {
        List<FlowRule> flowRules = new ArrayList<>();
        FlowRule flowRule = new FlowRule(KEY);
        // set limit qps to 20
        flowRule.setCount(20);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        flowRule.setLimitApp("default");
        flowRules.add(flowRule);
        FlowRuleManager.loadRules(flowRules);

        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource(KEY);
        // 80s内调用接口出现异常次数超过5的时候, 进行熔断
        rule.setCount(5);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
        rule.setTimeWindow(80);
        rules.add(rule);


        DegradeRuleManager.loadRules(rules);
    }
    /**
     * 流量消峰
     * @param useramdin
     * @param e
     * @return
     */
    public YoufanProduct findByidHandler(YoufanProduct youfanProduct, BlockException e) {
        logger.info("ProductServiceImpl findByidHandler"+ JSONObject.toJSONString(youfanProduct), e.toString());
        logger.info("流量超过限制，请稍后再试: " + youfanProduct.getId());
        //实际应该从数据库中查询,从备用库或者缓存中查询数据
        YoufanProduct youfanProduct1=new YoufanProduct();
        youfanProduct1.setBrandid(11L);
        youfanProduct1.setProductTypeid(12L);
        youfanProduct1.setProductAttributeValueId("12");
        youfanProduct1.setName("黄桃罐头");
        youfanProduct1.setTitle("黄桃");
        youfanProduct1.setPic("3.4");
        youfanProduct1.setPrice(3.6);
        return youfanProduct1;

    }

    public YoufanProduct findByidFallback(YoufanProduct youfanProduct, Throwable e) {
        logger.info("ProductServiceImpl findByidFallback"+ JSONObject.toJSONString(youfanProduct), e.toString());
        YoufanProduct youfanProduct1=new YoufanProduct();
        youfanProduct1.setBrandid(11L);
        youfanProduct1.setProductTypeid(12L);
        youfanProduct1.setProductAttributeValueId("12");
        youfanProduct1.setName("黄桃罐头");
        youfanProduct1.setTitle("黄桃");
        youfanProduct1.setPic("3.4");
        youfanProduct1.setPrice(3.6);
        return youfanProduct1;
    }

    /**
     * findByID流量消峰
     * @param useramdin
     * @param e
     * @return
     */
    public CommonPage<YoufanProduct> queryByCondtionBlockHandlerMethod(YoufanProduct youfanProduct, BlockException e) {
        logger.info("ProductServiceImpl blockHandler"+ JSONObject.toJSONString(youfanProduct), e.toString());
        logger.info("流量超过限制，请稍后再试: " + youfanProduct.getId());
        List<YoufanProduct> list=new ArrayList<YoufanProduct>();
        YoufanProduct youfanProduct1=new YoufanProduct();
        youfanProduct1.setBrandid(11L);
        youfanProduct1.setProductTypeid(12L);
        youfanProduct1.setProductAttributeValueId("12");
        youfanProduct1.setName("黄桃罐头");
        youfanProduct1.setTitle("黄桃");
        youfanProduct1.setPic("3.4");
        youfanProduct1.setPrice(3.6);
        list.add(youfanProduct1);
        return CommonPage.restPage(list);

    }

    public CommonPage<YoufanProduct> queryByCondtionFallback(YoufanProduct youfanProduct, Throwable e) {
        logger.info("ProductServiceImpl fallback"+ JSONObject.toJSONString(youfanProduct), e.toString());
        List<YoufanProduct> list=new ArrayList<YoufanProduct>();
        YoufanProduct youfanProduct1=new YoufanProduct();
        youfanProduct1.setBrandid(11L);
        youfanProduct1.setProductTypeid(12L);
        youfanProduct1.setProductAttributeValueId("12");
        youfanProduct1.setName("黄桃罐头");
        youfanProduct1.setTitle("黄桃");
        youfanProduct1.setPic("3.4");
        youfanProduct1.setPrice(3.6);
        list.add(youfanProduct1);
        return CommonPage.restPage(list);
    }
}
